﻿using Kimd.Common;
using Kimd.Communication;
using Kimd.Logic;
using Kimd.Machine;
using Kimd.Motion;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using WorkStation.Common;

namespace WorkStation.Logic
{
    //名称: 轨道下料
    public class RecycleTrayLogic : FlowBase
    {
        private PLCOperator _plc;
        private int _moduleIndex;
        private Tray _okTray1;
        private Tray _okTray2;
        public RecycleTrayLogic(string flowName, FlowManager flowmanager, int moduleIndex)
            : base(flowName, flowmanager)
        {
            this._moduleIndex = moduleIndex;
            _okTray1 = new Tray(1, 30);
            _okTray2 = new Tray(1, 30);
            _plc = MachineResource.Instance.MachinePLC["轨道PLC"];
        }

        public override void Calibrate()
        {
            base.Calibrate();
        }

        public override void Home()
        {
            _okTray1.Helper.NewFullTray();
            _okTray2.Helper.NewFullTray();
            if (_moduleIndex == 0)
                GlobalVariable.PCWritePLCData[(int)EnumHelper.GetEnumValueFromDescription<PLCOutFlag>("需下料空Tray")] = false;
            else
                GlobalVariable.PCWritePLCData[(int)EnumHelper.GetEnumValueFromDescription<PLCOutFlag>("需下料空Tray2")] = false;
            GlobalVariable.CurrentBackOKBoatSN = "";
            GlobalVariable.CurrentFrontOKBoatSN = "";
        }

        public override void Init(out string errInfo)
        {
            base.Init(out errInfo);
        }
        public override void InSingleRunMode()
        {
            if (GlobalVariable.OnSingleRunPause != null)
                GlobalVariable.OnSingleRunPause();
        }
        public override void Method()
        {
            if (!CheckFlowCondition()) return;
            if (GlobalVariable.IsSpotChecking) return;
            //向轨道要Tray
            if (/*!GlobalVariable.IsDryRun && */!SystemConfig.Instance.UsingStatus.IsConveyorSimulate)
            {
                if (!isAllowPut())
                {
                    MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"模组{_moduleIndex + 1}问轨道要空Tray", this.Description, 0, ""));
                    //先要料
                    if (_moduleIndex == 0)
                        GlobalVariable.PCWritePLCData[(int)EnumHelper.GetEnumValueFromDescription<PLCOutFlag>("需下料空Tray")] = true;
                    else
                        GlobalVariable.PCWritePLCData[(int)EnumHelper.GetEnumValueFromDescription<PLCOutFlag>("需下料空Tray2")] = true;
                    //运行条件检测
                    if (!CheckFlowCondition()) return;
                    MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"模组{_moduleIndex + 1}等待轨道空Tray到位", this.Description, 0, ""));
                    while (!isAllowPut() && !IsBreak() && !SystemConfig.Instance.UsingStatus.IsConveyorSimulate)
                    {
                        System.Threading.Thread.Sleep(2);
                    }
                    if (!CheckFlowCondition()) return;
                    //收到了允许放料的信号，需要读一下载具码
                    //if (SystemConfig.Instance.MesParam.EnableMES)
                    //{
                    if (_moduleIndex == 0)
                    {
                        GlobalVariable.CurrentFrontOKBoatSN = GetCarrierSN();
                        MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"读取到载具码{GlobalVariable.CurrentFrontOKBoatSN}", this.Description, 0, ""));
                    }
                    else
                    {
                        GlobalVariable.CurrentBackOKBoatSN = GetCarrierSN();
                        MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"读取到载具码{GlobalVariable.CurrentBackOKBoatSN}", this.Description, 0, ""));
                    }
                    //}
                    MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"模组{_moduleIndex + 1}复位要空Tray信号", this.Description, 0, ""));
                    if (_moduleIndex == 0)
                        GlobalVariable.PCWritePLCData[(int)EnumHelper.GetEnumValueFromDescription<PLCOutFlag>("需下料空Tray")] = false;
                    else
                        GlobalVariable.PCWritePLCData[(int)EnumHelper.GetEnumValueFromDescription<PLCOutFlag>("需下料空Tray2")] = false;

                    if (!SystemConfig.Instance.UsingStatus.IsTestTrackEnable)
                    { //lock (GlobalVariable.OKTrayLock)
                        {
                            _okTray1.Helper.NewEmptyTray();
                            _okTray2.Helper.NewEmptyTray();
                        }
                    }
                    else
                    {
                        MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"模组{_moduleIndex + 1}测试流道下料", this.Description, 0, ""));
                        Thread.Sleep(5000);
                    }

                }
            }
            else
            {
                Thread.Sleep(500);
            }
            if (!SystemConfig.Instance.UsingStatus.IsTestTrackEnable)
            {
                _okTray1.Helper.NewEmptyTray();
                _okTray2.Helper.NewEmptyTray();
            }
            if (_moduleIndex == 0)
            {
                if (GlobalVariable.NeedRecycleEmptyBoatTray1)
                {
                    GlobalVariable.NeedRecycleEmptyBoatTray1 = false;
                    GlobalVariable.NeedRecycleEmptyBoatTrayFinish1 = true;
                    MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"模组{_moduleIndex + 1}强制下空boat,供Tray完成", this.Description, 0, ""));
                }
            }
            else
            {
                if (GlobalVariable.NeedRecycleEmptyBoatTray2)
                {
                    GlobalVariable.NeedRecycleEmptyBoatTray2 = false;
                    GlobalVariable.NeedRecycleEmptyBoatTrayFinish2 = true;
                    MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"模组{_moduleIndex + 1}强制下空boat,供Tray完成", this.Description, 0, ""));
                }
            }
            //等待放料满
            MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"模组{_moduleIndex + 1}等待放满料", this.Description, 0, ""));
            if (_moduleIndex == 0)
            {
                while (((!_okTray1.Helper.IsFull || !_okTray2.Helper.IsFull) && !GlobalVariable.NeedRecycleEmptyBoatTray1 && !SystemConfig.Instance.UsingStatus.IsTestTrackEnable)
                    && !IsBreak() && !GlobalVariable.IsClearDownTray /*&& !GlobalVariable.IsClearFinish*/)
                {
                    Thread.Sleep(20);
                }
                if (GlobalVariable.NeedRecycleEmptyBoatTray1)
                {
                    MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"模组{_moduleIndex + 1}强制下空boat", this.Description, 0, ""));
                }
            }
            else
            {
                while (((!_okTray1.Helper.IsFull || !_okTray2.Helper.IsFull) && !GlobalVariable.NeedRecycleEmptyBoatTray2 && !SystemConfig.Instance.UsingStatus.IsTestTrackEnable)
                    && !IsBreak() && !GlobalVariable.IsClearDownTray2 /*&& !GlobalVariable.IsClearFinish*/)
                {
                    Thread.Sleep(20);
                }
                if (GlobalVariable.NeedRecycleEmptyBoatTray2)
                {
                    MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"模组{_moduleIndex + 1}强制下空boat", this.Description, 0, ""));
                }
            }
            if (!CheckFlowCondition()) return;
            MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"模组{_moduleIndex + 1}料满了，告诉轨道放空Tray完成了", this.Description, 0, ""));
            if (_moduleIndex == 0)
                GlobalVariable.PCWritePLCData[(int)EnumHelper.GetEnumValueFromDescription<PLCOutFlag>("放下料空Tray完成")] = true;
            else
                GlobalVariable.PCWritePLCData[(int)EnumHelper.GetEnumValueFromDescription<PLCOutFlag>("放下料空Tray完成2")] = true;
            Thread.Sleep(1000);
            MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"等待轨道{_moduleIndex + 1}下料完成", this.Description, 0, ""));
            while (!isUnloadFullTrayFinish() && !IsBreak() && !SystemConfig.Instance.UsingStatus.IsConveyorSimulate)
            {
                Thread.Sleep(20);
            }
            if (!CheckFlowCondition()) return;
            MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.Log, $"轨道{_moduleIndex + 1}下料完成  OK", this.Description, 0, ""));
            if (_moduleIndex == 0)
                GlobalVariable.PCWritePLCData[(int)EnumHelper.GetEnumValueFromDescription<PLCOutFlag>("放下料空Tray完成")] = false;
            else
                GlobalVariable.PCWritePLCData[(int)EnumHelper.GetEnumValueFromDescription<PLCOutFlag>("放下料空Tray完成2")] = false;
            #region 只在精定位发出清下料盘信号是起作用
            if (_moduleIndex == 0)
            {
                if (GlobalVariable.IsClearDownTray)
                {
                    GlobalVariable.IsClearDownTrayFinish = true;
                    while (GlobalVariable.IsClearDownTray && !IsBreak())
                    {
                        Thread.Sleep(20);
                    }
                    if (!CheckFlowCondition()) return;
                }
            }
            else
            {
                if (GlobalVariable.IsClearDownTray2)
                {
                    GlobalVariable.IsClearDownTrayFinish2 = true;
                    while (GlobalVariable.IsClearDownTray2 && !IsBreak())
                    {
                        Thread.Sleep(20);
                    }
                    if (!CheckFlowCondition()) return;
                }
            }
            #endregion
            if (!CheckFlowCondition()) return;
            //等待清料结束才再要料
            //if (_moduleIndex == 0)
            //{
            //    while (GlobalVariable.IsClearLater || GlobalVariable.IsClearNow)
            //    {
            //        Thread.Sleep(20);
            //    }
            //}
            //else
            //{
            //    while (GlobalVariable.IsClearLater2 || GlobalVariable.IsClearNow2)
            //    {
            //        Thread.Sleep(20);
            //    }
            //}
            if (!CheckFlowCondition()) return;
        }

        public override void OnStop()
        {
            base.OnStop();
        }

        public override bool PreStartCheck()
        {
            return base.PreStartCheck();
        }
        private bool isAllowPut()
        {
            if (_moduleIndex == 0)
                return GlobalVariable.PCReadPLCData[(int)EnumHelper.GetEnumValueFromDescription<PLCInFlag>("允许放下料空Tray")];
            else
                return GlobalVariable.PCReadPLCData[(int)EnumHelper.GetEnumValueFromDescription<PLCInFlag>("允许放下料空Tray2")];
        }
        short[] snvals = null;
        public string GetCarrierSN()
        {
            lock (GlobalVariable.ConveyorPLCLock)
            {
                if (_moduleIndex == 0)
                {
                    //while (!ReadPLC(_plc, RegisterType.D, 700, 25, out snvals))
                    //{
                    //    Thread.Sleep(40);
                    //}
                    GlobalVariable.ConveyorPLC.ReadShort("700", 25, out snvals);
                }
                else
                {
                    //while (!ReadPLC(_plc, RegisterType.D, 750, 25, out snvals))
                    //{
                    //    Thread.Sleep(40);
                    //}
                    GlobalVariable.ConveyorPLC.ReadShort("750", 25, out snvals);
                }
            }
            if (snvals != null)
                return CommonMethod.ConvertShortArrayToString(snvals);
            return "NoSN";
        }
        private bool isUnloadFullTrayFinish()
        {
            if (_moduleIndex == 0)
                return GlobalVariable.PCReadPLCData[(int)EnumHelper.GetEnumValueFromDescription<PLCInFlag>("下满Tray完成")];
            else
                return GlobalVariable.PCReadPLCData[(int)EnumHelper.GetEnumValueFromDescription<PLCInFlag>("下满Tray完成2")];
        }
        public Tray GetOKTray1()
        {
            return _okTray1;
        }
        public Tray GetOKTray2()
        {
            return _okTray2;
        }
    }
}
